/*
 * Copyright 2008 Georgi Staykov
 * 
 * This file is part of pscoder.
 *
 * pscoder is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * pscoder is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with pscoder.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.gstaykov.pscoder.editor.syntax;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.jface.text.TextAttribute;
import org.eclipse.jface.text.rules.EndOfLineRule;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
import org.eclipse.jface.text.rules.RuleBasedScanner;
import org.eclipse.jface.text.rules.SingleLineRule;
import org.eclipse.jface.text.rules.Token;
import org.eclipse.jface.text.rules.WordRule;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.widgets.Display;

public class PowershellCodeScanner extends RuleBasedScanner {
	private static String[] keywords = {"if", "else", "elseif", "switch", "while", "foreach", "default", "for", "do", "until", "break", 
										"continue", "function", "return", "where", "filter", "in", "trap", "throw", "param"};
	private static String[] dashKeywords = {"-eq", "-ne", "-ge", "-gt", "-lt", "-le", "-like", "-notlike", "-match", "-notmatch", "-replace", "-contains", "-notcontains",
											"-ieq", "-ine", "-ige", "-igt", "-ile", "-ilt", "-ilike", "-inotlike", "-imatch", "-inotmatch", "-ireplace",
											"-icontains", "-inotcontains", "-ceq", "-cne", "-cge", "-cgt", "-cle", "-clt", "-clike", "-cnotlike", "-f", 
											"-cmatch", "-cnotmatch", "-creplace", "-ccontains", "-cnotcontains", "-is", "-isnot", "-as", "-and", "-or", "-band", "-bor", "-not"};
	private static String[] scopes = {"$script", "$global", "$function", "$local", "$private"};
	
	public PowershellCodeScanner(PowershellColors pscolors) {

		IToken comment = new Token(new TextAttribute(new Color(Display.getCurrent(), PowershellColors.COMMENT)));
		IToken string = new Token(new TextAttribute(new Color(Display.getCurrent(), PowershellColors.STRING)));
		IToken variable = new Token(new TextAttribute(new Color(Display.getCurrent(), PowershellColors.VARIABLE)));
		IToken scope = new Token(new TextAttribute(new Color(Display.getCurrent(), PowershellColors.VARIABLE), null, SWT.BOLD));
		IToken keyword = new Token(new TextAttribute(new Color(Display.getCurrent(), PowershellColors.KEYWORD), null, SWT.BOLD));
		IToken dashKeyword = new Token(new TextAttribute(new Color(Display.getCurrent(), PowershellColors.DASH_KEYWORD), null, SWT.BOLD));

		List<IRule> rules= new ArrayList<IRule>();

		// Add rule for single line comments.
		rules.add(new EndOfLineRule("#", comment));

		// Add rule for strings and character constants.
		rules.add(new SingleLineRule("\"", "\"", string, '`', false, true));
		rules.add(new SingleLineRule("'", "'", string));

		// Add word rule for keywords, types, and constants.
		
		PowershellVariableDetector variableDetector = new PowershellVariableDetector(scope, variable);
		for (int i = 0; i < scopes.length; i++)
			variableDetector.addScope(scopes[i]);
		rules.add(variableDetector);
		
		WordRule wordRule = new WordRule(new PowershellWordDetector());
		for (int i = 0; i < keywords.length; i++)
			wordRule.addWord(keywords[i], keyword);
		rules.add(wordRule);

		wordRule = new WordRule(new PowershellDashOperatorDetector());
		for (int i = 0; i < dashKeywords.length; i++)
			wordRule.addWord(dashKeywords[i], dashKeyword);
		rules.add(wordRule);
		
		IRule[] result= new IRule[rules.size()];
		rules.toArray(result);
		setRules(result);
	}
}
